#ifndef __I_EVENT_H__
#define __I_EVENT_H__

/************EventCode****************/
#define EVENT_NONE CONTINUATION_EVENT_NONE //0
#define EVENT_IMMDIATE (EVENT_NONE+1)
#define EVENT_INTERVAL (EVENT_NONE+2)
#define EVENT_POLL (EVENT_NONE+3)

#define NET_EVENT_START		100
/*#define AIO_EVENT_START		200*/

/***********ReturnCode**************/
#define EVENT_CONT 0
#define EVENT_RETURN (EVENT_CONT+1)
#define EVENT_DONE (EVENT_CONT+2)

#include "I_Action.h"
#include <zlib/lib/Ink_time.h>

class Event : public Action
{
public:
	EThread *ethread;
	ink_hrtime timeout_at;
	ink_hrtime period;

	unsigned int immediate : 1; //timeout_at = period = 0

	int callback_event;

	Event() : ethread(NULL), timeout_at(0), period(0), callback_event(EVENT_NONE), in_queue(0)
	{}

	void free()
	{
		delete this;
	}

	//if c has mutex, the Event object mutex is c->mutex
	//else the Event object mutex is EThread->mutex
	Event *init(Continuation *c, ink_hrtime atimeout_at = 0, ink_hrtime aperiod = 0)
	{
		continuation = c;
		timeout_at = atimeout_at;
		period = aperiod;
		immediate = !period && !timeout_at;

		cancelled = false;
		return this;
	}

	void schedule_imm(int acallback_event = EVENT_IMMDIATE);
	void schedule_at(ink_hrtime t, int acallback_event = EVENT_INTERVAL);
	void schedule_every(ink_hrtime t, int acallback_event = EVENT_INTERVAL);

	int in_queue : 1;

private:
	Event(const Event &);
	Event &operator=(const Event &);

};

#endif //__I_EVENT_H__
